# Copyright (C) 2006-2008 by Sergio Pistone
# sergio_pistone@yahoo.com.ar
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

begin
	require "Qt3"
rescue LoadError
	require "Qt"
	raise LoadError.new( "Wrong Qt version found (Qt3 expected but Qt4 found)" ) if defined?( Qt::StringListModel )
end
require "date"
require File.expand_path( File.dirname( __FILE__ ) + "/../i18n/i18n" )
$KCODE="u" # unicode support

module QT3

	def QT3.empty_string?( text )
		return text ? (text.empty? ? true : text.strip().empty? ) : true
	end

	class BaseDialog < Qt::Dialog

		attr_reader :values

		def initialize( values )
			super( nil )
			@values = values
		end

		def create_action_buttons( mode="right", accept_text=nil, cancel_text= nil )
			accept_text = QT3.empty_string?( accept_text ) ? I18n.get( "gui.common.accept" ) : accept_text
			cancel_text = QT3.empty_string?( cancel_text ) ? I18n.get( "gui.common.cancel" ) : cancel_text
			@accept_button = Qt::PushButton.new( accept_text, self )
			@cancel_button = Qt::PushButton.new( cancel_text, self )
			connect( @accept_button, SIGNAL( "clicked()" ), self, SLOT( "accept()" ) )
			connect( @cancel_button, SIGNAL( "clicked()" ), self, SLOT( "reject()" ) )
			if mode == "left"
				hbox = Qt::HBoxLayout.new( 4 )
 				hbox.setDirection( Qt::BoxLayout::LeftToRight )
				hbox.addWidget( @accept_button )
				hbox.addWidget( @cancel_button )
				hbox.addStretch()
			elsif mode == "split"
				hbox = Qt::HBoxLayout.new( 4 )
				hbox.addWidget( @accept_button, 1 )
				hbox.addWidget( @cancel_button, 1 )
			else
				hbox = Qt::HBoxLayout.new( 4 )
				hbox.addStretch()
				hbox.addWidget( @accept_button )
				hbox.addWidget( @cancel_button )
			end
			return hbox
		end
		protected :create_action_buttons

		def accepted()
			return result() == Qt::Dialog.Accepted
		end
	end

	class PluginsManagerDialog < BaseDialog

		slots "move_up()", "move_down()", "add_plugin()", "remove_plugin()"

		def initialize( values )
			super( values )

			setCaption( I18n.get( "gui.pluginsmanager.title", @values["script_name"] ) )

			sites_group = Qt::GroupBox.new( I18n.get( "gui.pluginsmanager.sites" ), self )

			@move_up_button = Qt::PushButton.new( I18n.get( "gui.pluginsmanager.sites.moveup" ), sites_group )
			@move_down_button = Qt::PushButton.new( I18n.get( "gui.pluginsmanager.sites.movedown" ), sites_group )

			@used_plugins_list = Qt::ListView.new( sites_group )
			@used_plugins_list.setSelectionMode( Qt::ListView::Single )
			@used_plugins_list.addColumn( I18n.get( "gui.pluginsmanager.sites.inuse" ), -1 )
			@used_plugins_list.setResizeMode( Qt::ListView::LastColumn )
			@used_plugins_list.setSorting( -1 )
			@values["used_plugins"].reverse().each() do |plugin|
				item = Qt::ListViewItem.new( @used_plugins_list, plugin )
				@used_plugins_list.insertItem( item )
			end

			@add_button = Qt::PushButton.new( I18n.get( "gui.pluginsmanager.sites.add" ), sites_group )
			@remove_button = Qt::PushButton.new( I18n.get( "gui.pluginsmanager.sites.remove" ), sites_group )

			@unused_plugins_list = Qt::ListView.new( sites_group )
			@unused_plugins_list.setSelectionMode( Qt::ListView::Single )
			@unused_plugins_list.addColumn( I18n.get( "gui.pluginsmanager.sites.available" ), -1 )
			@unused_plugins_list.setResizeMode( Qt::ListView::LastColumn )
			@unused_plugins_list.setSorting( -1 )
			@values["unused_plugins"].reverse().each() do |plugin|
				item = Qt::ListViewItem.new( @unused_plugins_list, plugin )
				@unused_plugins_list.insertItem( item )
			end

			misc_group = Qt::GroupBox.new( 1, Qt::Horizontal, I18n.get( "gui.pluginsmanager.misc" ), self )

			@cleanup_lyrics_checkbox = Qt::CheckBox.new( misc_group )
			@cleanup_lyrics_checkbox.setChecked( values["cleanup_lyrics"].to_s() == "true" )
			@cleanup_lyrics_checkbox.setText( I18n.get( "gui.pluginsmanager.misc.cleanup" ) )

			@single_threaded_checkbox = Qt::CheckBox.new( misc_group )
			@single_threaded_checkbox.setChecked( values["single_threaded"].to_s() == "true" )
			@single_threaded_checkbox.setText( I18n.get( "gui.pluginsmanager.misc.singlethreaded" ) )

			@write_log_checkbox = Qt::CheckBox.new( misc_group )
			@write_log_checkbox.setChecked( values["write_log"].to_s() == "true" )
			@write_log_checkbox.setText( I18n.get( "gui.pluginsmanager.misc.writelog", "$HOME/.wikilyrics.log" ) )

			buttons = create_action_buttons()

			sites_group_layout = Qt::GridLayout.new( sites_group, 5, 4, 5 )
			sites_group_layout.setRowSpacing( 0, 12 )
			sites_group_layout.setColStretch( 1, 1 )
			sites_group_layout.setColStretch( 3, 1 )
			sites_group_layout.setRowStretch( 1, 1 )
			sites_group_layout.setRowStretch( 4, 1 )
			sites_group_layout.addWidget( @move_up_button, 2, 0 )
			sites_group_layout.addWidget( @move_down_button, 3, 0 )
			sites_group_layout.addMultiCellWidget( @used_plugins_list, 1, 4, 1, 1 )
			sites_group_layout.addWidget( @add_button, 2, 2 )
			sites_group_layout.addWidget( @remove_button, 3, 2 )
			sites_group_layout.addMultiCellWidget( @unused_plugins_list, 1, 4, 3, 3 )

			layout = Qt::VBoxLayout.new( self, 5 )
			layout.addWidget( sites_group )
			layout.addWidget( misc_group )
			layout.addLayout( buttons )

			connect( @move_up_button, SIGNAL( "clicked()" ), self, SLOT( "move_up()" ) )
			connect( @move_down_button, SIGNAL( "clicked()" ), self, SLOT( "move_down()" ) )
			connect( @add_button, SIGNAL( "clicked()" ), self, SLOT( "add_plugin()" ) )
			connect( @remove_button, SIGNAL( "clicked()" ), self, SLOT( "remove_plugin()" ) )

			update_accept_button()

			resize( 400, 280 )
		end

		# workaround for buggy qlistview (works as expected only when sorting is disabled)
		def list_view_move_item( list_view, item, after )
			return if item == after
			if after
				item.moveItem( after )
			else
				list_view.takeItem( item )
				list_view.insertItem( item )
			end
		end

		def move_up()
			cur_item = @used_plugins_list.currentItem()
			return if cur_item == nil
			prev_item = cur_item.itemAbove()
			return if prev_item == nil
			prev_item = prev_item.itemAbove()
			list_view_move_item( @used_plugins_list, cur_item, prev_item )
			@used_plugins_list.setCurrentItem( cur_item )
		end

		def move_down()
			cur_item = @used_plugins_list.currentItem()
			return if cur_item == nil
			next_item = cur_item.itemBelow()
			return if next_item == nil
			list_view_move_item( @used_plugins_list, cur_item, next_item )
			@used_plugins_list.setCurrentItem( cur_item )
		end

		def add_plugin()
			unused_cur_item = @unused_plugins_list.currentItem()
			return if unused_cur_item == nil
			@unused_plugins_list.takeItem( unused_cur_item )
			@used_plugins_list.insertItem( unused_cur_item )
			list_view_move_item( @used_plugins_list, unused_cur_item, @used_plugins_list.lastItem() )
			@used_plugins_list.setCurrentItem( unused_cur_item )
			update_accept_button()
		end

		def remove_plugin()
			used_cur_item = @used_plugins_list.currentItem()
			return if used_cur_item == nil
			@used_plugins_list.takeItem( used_cur_item )
			@unused_plugins_list.insertItem( used_cur_item )
			list_view_move_item( @unused_plugins_list, used_cur_item, @unused_plugins_list.lastItem() )
			@unused_plugins_list.setCurrentItem( used_cur_item )
			update_accept_button()
		end

		def update_accept_button()
			@accept_button.setEnabled( @used_plugins_list.childCount() > 0 )
		end

		def accept()
			@values = {
				"cleanup_lyrics" => @cleanup_lyrics_checkbox.isChecked(),
				"single_threaded" => @single_threaded_checkbox.isChecked(),
				"write_log" => @write_log_checkbox.isChecked(),
				"used_plugins" => [],
				"script_name" => @values["script_name"],
				"unused_plugins" => []
			}
			child = @used_plugins_list.firstChild()
			while ( child )
				@values["used_plugins"].insert( -1, child.text( 0 ) )
				child = child.itemBelow()
			end
			child = @unused_plugins_list.firstChild()
			while ( child )
				@values["unused_plugins"].insert( -1, child.text( 0 ) )
				child = child.itemBelow()
			end
			super()
		end

	end


	class WikiPluginDialog < BaseDialog

		slots "toggle_submit_checked( bool )"
		slots "toggle_review_checked( bool )"
		slots "update_accept_button_state()"

		def initialize( values )
			super( values )

			setCaption( I18n.get( "gui.wikiplugin.title", values["site_name"] ) )

			general_group = Qt::GroupBox.new( I18n.get( "gui.wikiplugin.general" ), self )
			general_group.setColumnLayout( 0, Qt::Vertical )
			general_group.layout().setSpacing( 5 )

			@submit_checkbox = Qt::CheckBox.new( general_group )
			@submit_checkbox.setChecked( values["submit"].to_s() == "true" )
			@submit_checkbox.setText( I18n.get( "gui.wikiplugin.general.submit", values["site_name"] ) )

			@review_checkbox = Qt::CheckBox.new( general_group )
			@review_checkbox.setEnabled( @submit_checkbox.isChecked() )
			@review_checkbox.setChecked( @review_checkbox.isEnabled() && values["review"].to_s() == "true" )
			@review_checkbox.setText( I18n.get( "gui.wikiplugin.general.review" ) )

			@prompt_autogen_checkbox = Qt::CheckBox.new( general_group )
			@prompt_autogen_checkbox.setEnabled( @review_checkbox.isChecked() )
			@prompt_autogen_checkbox.setChecked( @prompt_autogen_checkbox.isEnabled() && values["prompt_autogen"].to_s() == "true" )
			@prompt_autogen_checkbox.setText( I18n.get( "gui.wikiplugin.general.autogen" ) )

			@prompt_no_lyrics_checkbox = Qt::CheckBox.new( general_group )
			@prompt_no_lyrics_checkbox.setEnabled( @review_checkbox.isChecked() )
			@prompt_no_lyrics_checkbox.setChecked( @prompt_no_lyrics_checkbox.isEnabled() && values["prompt_no_lyrics"].to_s() == "true" )
			@prompt_no_lyrics_checkbox.setText( I18n.get( "gui.wikiplugin.general.nolyrics" ) )

			login_group = Qt::GroupBox.new( I18n.get( "gui.wikiplugin.login" ), self )
			login_group.setColumnLayout( 0, Qt::Vertical )
			login_group.layout().setSpacing( 5 )

			username_label = Qt::Label.new( I18n.get( "gui.wikiplugin.login.username" ), login_group )
			@username_lineedit = Qt::LineEdit.new( values["username"], login_group )

			password_label = Qt::Label.new( I18n.get( "gui.wikiplugin.login.password" ), login_group )
			@password_lineedit = Qt::LineEdit.new( values["password"], login_group )
			@password_lineedit.setEchoMode( Qt::LineEdit::Password )

			buttons = create_action_buttons()
			update_accept_button_state()

			general_group_layout = Qt::GridLayout.new( general_group.layout() )
			general_group_layout.setAlignment( Qt::AlignTop )
			general_group_layout.addMultiCellWidget( @submit_checkbox, 0, 0, 0, 1 )
			general_group_layout.addMultiCellWidget( @review_checkbox, 1, 1, 0, 1 )
			general_group_layout.addMultiCellWidget( @prompt_autogen_checkbox, 2, 2, 0, 1 )
			general_group_layout.addMultiCellWidget( @prompt_no_lyrics_checkbox, 3, 3, 0, 1 )

			login_group_layout = Qt::GridLayout.new( login_group.layout() )
			login_group_layout.setAlignment( Qt::AlignTop )
			login_group_layout.addWidget( username_label, 1, 0 );
			login_group_layout.addWidget( @username_lineedit, 1, 1 );
			login_group_layout.addWidget( password_label, 2, 0 )
			login_group_layout.addWidget( @password_lineedit, 2, 1 )

			layout = Qt::GridLayout.new( self, 1, 1, 5 )
			layout.addMultiCellWidget( general_group, 0, 0, 0, 2 )
			layout.addMultiCellWidget( login_group, 1, 1, 0, 2 )
			layout.addItem( Qt::SpacerItem.new( 81, 20, Qt::SizePolicy::Expanding, Qt::SizePolicy::Minimum ), 2, 0 );
			layout.addMultiCellLayout( buttons, 2, 2, 0, 2 )

			connect( @username_lineedit, SIGNAL( "textChanged(const QString&)" ), self, SLOT( "update_accept_button_state()" ) )
			connect( @submit_checkbox, SIGNAL( "toggled(bool)" ), self, SLOT( "toggle_submit_checked(bool)" ) )
			connect( @review_checkbox, SIGNAL( "toggled(bool)" ), self, SLOT( "toggle_review_checked(bool)" ) )

			resize( 300, 50 )
		end

		def toggle_submit_checked( checked )
			@review_checkbox.setEnabled( checked )
			if ! checked
				@review_checkbox.setChecked( false )
				@prompt_autogen_checkbox.setChecked( false )
				@prompt_no_lyrics_checkbox.setChecked( false )
			end
			update_accept_button_state()
		end

		def toggle_review_checked( checked )
			@prompt_autogen_checkbox.setEnabled( checked )
			@prompt_no_lyrics_checkbox.setEnabled( checked )
			if ! checked
				@prompt_autogen_checkbox.setChecked( false )
				@prompt_no_lyrics_checkbox.setChecked( false )
			end
		end

		def update_accept_button_state()
			@accept_button.setEnabled( ! @submit_checkbox.isChecked() || ! @username_lineedit.text().empty? )
		end

		def accept()
			@values = {
				"submit"			=> @submit_checkbox.isChecked(),
				"review"			=> @review_checkbox.isChecked(),
				"prompt_autogen"	=> @prompt_autogen_checkbox.isChecked(),
				"prompt_no_lyrics"	=> @prompt_no_lyrics_checkbox.isChecked(),
				"username"			=> @username_lineedit.text(),
				"password"			=> @password_lineedit.text(),
			}
			super()
		end

	end

	class SubmitSongDialog < BaseDialog

		slots "toggle_instrumental_checked( bool )"

		def initialize( values )
			super( values )

			edit_mode = @values["edit_mode"].to_s() == "true"
			setCaption( I18n.get( "gui.submitsong.title." + (edit_mode ? "edit" : "submit"), values["site_name"] ) )

			artist_label = Qt::Label.new( "<b>#{I18n.get( "gui.common.artist" )}</b>", self )
			@artist_lineedit = Qt::LineEdit.new( values["artist"], self )

			title_label = Qt::Label.new( "<b>#{I18n.get( "gui.common.song" )}</b>", self )
			@title_lineedit = Qt::LineEdit.new( values["title"], self )

			credits_label = Qt::Label.new( "<b>#{I18n.get( "gui.common.credits" )}</b>", self )
			@credits_lineedit = Qt::LineEdit.new( values["credits"], self )

			lyricist_label = Qt::Label.new( "<b>#{I18n.get( "gui.common.lyricist" )}</b>", self )
			@lyricist_lineedit = Qt::LineEdit.new( values["lyricist"], self )

			year_label = Qt::Label.new( "<b>#{I18n.get( "gui.common.year" )}</b>", self )
			@year_spinbox = Qt::SpinBox.new( self )
			@year_spinbox.setMinValue( 1900 )
			@year_spinbox.setMaxValue( Date.today().year )
			@year_spinbox.setValue( values["year"] )

			album_label = Qt::Label.new( "<b>#{I18n.get( "gui.common.album" )}</b>", self )
			@album_lineedit = Qt::LineEdit.new( values["album"], self )

			@instrumental_checkbox = Qt::CheckBox.new( self )
			@instrumental_checkbox.setChecked( @values["instrumental"].to_s() == "true" )
			@instrumental_checkbox.setText( I18n.get( "gui.submitsong.instrumental" ) )

			@lyrics_text = Qt::TextEdit.new( self )
			@lyrics_text.setTextFormat( Qt::TextEdit::PlainText )
			@lyrics_text.setText( values["lyrics"] )
			@lyrics_text.setDisabled( @instrumental_checkbox.isChecked() )

			@reviewed_checkbox = Qt::CheckBox.new( self )
			@reviewed_checkbox.setChecked( false )
			@reviewed_checkbox.setText( I18n.get( "gui.common.reviewed" ) )

			buttons = create_action_buttons( "split", I18n.get( "gui.common.submit" ) )

			grid_layout = Qt::GridLayout.new( self, 9, 5, 5 )
			grid_layout.addColSpacing( 2, 15 )
			grid_layout.addWidget( artist_label, 0, 0, Qt::AlignRight )
			grid_layout.addWidget( @artist_lineedit, 0, 1 )
			grid_layout.addWidget( title_label, 0, 3, Qt::AlignRight )
			grid_layout.addWidget( @title_lineedit, 0, 4 )
			grid_layout.addWidget( credits_label, 1, 0, Qt::AlignRight )
			grid_layout.addWidget( @credits_lineedit, 1, 1 )
			grid_layout.addWidget( lyricist_label, 1, 3, Qt::AlignRight )
			grid_layout.addWidget( @lyricist_lineedit, 1, 4 )
			grid_layout.addWidget( year_label, 2, 0, Qt::AlignRight )
			grid_layout.addWidget( @year_spinbox, 2, 1 )
			grid_layout.addWidget( album_label, 2, 3, Qt::AlignRight )
			grid_layout.addWidget( @album_lineedit, 2, 4 )
			grid_layout.addMultiCellWidget( @instrumental_checkbox, 3, 3, 0, 4 )
			grid_layout.addMultiCellWidget( @lyrics_text, 4, 4, 0, 4 )
			grid_layout.addMultiCellWidget( @reviewed_checkbox, 5, 5, 0, 4 )
			grid_layout.addMultiCellLayout( buttons, 6, 6, 0, 4 )

			resize( 600, 400 )

			connect( @instrumental_checkbox, SIGNAL( "toggled(bool)" ), self, SLOT( "toggle_instrumental_checked(bool)" ) )

		end

		def toggle_instrumental_checked( checked )
			@lyrics_text.setDisabled( checked )
		end

		def accept()
			@values = {
				"artist"		=> @artist_lineedit.text(),
				"year"			=> @year_spinbox.value(),
				"album"			=> @album_lineedit.text(),
				"title"			=> @title_lineedit.text(),
				"lyrics"		=> @lyrics_text.text(),
				"instrumental"	=> @instrumental_checkbox.isChecked(),
				"lyricist"		=> @lyricist_lineedit.text(),
				"credits"		=> @credits_lineedit.text(),
				"reviewed"		=> @reviewed_checkbox.isChecked()
			}
			super()
		end

	end

	class SubmitAlbumDialog < BaseDialog

		slots "browse_image()"

		def initialize( values )
			super( values )

			setCaption( I18n.get( "gui.submitalbum.title", values["site_name"] ) )

			artist_label = Qt::Label.new( "<b>#{I18n.get( "gui.common.artist" )}</b>", self )
			@artist_lineedit = Qt::LineEdit.new( values["artist"], self )

			year_label = Qt::Label.new( "<b>#{I18n.get( "gui.common.year" )}</b>", self )
			@year_spinbox = Qt::SpinBox.new( self )
			@year_spinbox.setMinValue( 1900 )
			@year_spinbox.setMaxValue( Date.today().year )
			@year_spinbox.setValue( values["year"].to_i() )

			month_label = Qt::Label.new( "<b>#{I18n.get( "gui.common.month" )}</b>", self )
			@month_spinbox = Qt::SpinBox.new( self )
			@month_spinbox.setMinValue( 0 )
			@month_spinbox.setMaxValue( 12 )
			@month_spinbox.setValue( values["month"].to_i() )

			day_label = Qt::Label.new( "<b>#{I18n.get( "gui.common.day" )}</b>", self )
			@day_spinbox = Qt::SpinBox.new( self )
			@day_spinbox.setMinValue( 0 )
			@day_spinbox.setMaxValue( 31 )
			@day_spinbox.setValue( values["day"].to_i() )

			album_label = Qt::Label.new( "<b>#{I18n.get( "gui.common.album" )}</b>", self )
			@album_lineedit = Qt::LineEdit.new( values["album"], self )

			image_label = Qt::Label.new( "<b>#{I18n.get( "gui.common.image" )}</b>", self )
			image_label.setAlignment( Qt::AlignLeft )

			@image_path_lineedit = Qt::LineEdit.new( values["image_path"], self )
			if ! values.include?( "image_path" )
				@image_path_lineedit.setEnabled( false )
				@image_path_lineedit.setText( I18n.get( "gui.submitalbum.coverfound" ) )
			else
				@image_button = Qt::PushButton.new( "...", self )
				connect( @image_button, SIGNAL( "clicked()" ), self, SLOT( "browse_image()" ) )
			end

			@tracks_text = Qt::TextEdit.new( self )
			@tracks_text.setWordWrap( Qt::TextEdit::NoWrap )
			@tracks_text.setTextFormat( Qt::PlainText )
			@tracks_text.setText( values["tracks"] )

			@reviewed_checkbox = Qt::CheckBox.new( self )
			@reviewed_checkbox.setChecked( false )
			@reviewed_checkbox.setText( I18n.get( "gui.common.reviewed" ) )

			buttons = create_action_buttons( "split", I18n.get( "gui.common.submit" ) )

			image_layout = Qt::HBoxLayout.new( 5 )
			image_layout.addWidget( @image_path_lineedit )
			image_layout.addWidget( @image_button ) if @values.include?( "image_path" )

			grid_layout = Qt::GridLayout.new( self )
			grid_layout.setMargin( 5 )
			grid_layout.setSpacing( 5 )
			grid_layout.setColStretch( 1, 2 )
			grid_layout.setColStretch( 3, 2 )
			grid_layout.setColStretch( 5, 2 )
			grid_layout.addWidget( artist_label, 0, 0, Qt::AlignRight )
			grid_layout.addMultiCellWidget( @artist_lineedit, 0, 0, 1, 5 )
			grid_layout.addWidget( album_label, 1, 0, Qt::AlignRight )
			grid_layout.addMultiCellWidget( @album_lineedit, 1, 1, 1, 5 )
			grid_layout.addWidget( year_label, 2, 0, Qt::AlignRight )
			grid_layout.addWidget( @year_spinbox, 2, 1 )
			grid_layout.addWidget( month_label, 2, 2, Qt::AlignRight )
			grid_layout.addWidget( @month_spinbox, 2, 3 )
			grid_layout.addWidget( day_label, 2, 4, Qt::AlignRight )
			grid_layout.addWidget( @day_spinbox, 2, 5 )
			grid_layout.addWidget( image_label, 3, 0, Qt::AlignRight )
			grid_layout.addMultiCellLayout( image_layout, 3, 3, 1, 5 )
			grid_layout.addMultiCellWidget( @tracks_text, 4, 4, 0, 5 )
			grid_layout.addMultiCellWidget( @reviewed_checkbox, 5, 5, 0, 5 )
			grid_layout.addMultiCellLayout( buttons, 6, 6, 0, 5 )

			resize( 600, 400 )
		end

		def browse_image()
			dirname = @image_path_lineedit.text().strip()
			dirname = QT3.empty_string?( dirname ) ? (ENV["HOME"] ? ENV["HOME"] : ".") : File.dirname( dirname )
			dialog = Qt::FileDialog.new(
				dirname,
				I18n.get( "gui.uploadcover.browseimage.images" ) + " (*.jpg *.JPG *.png *.PNG *.bmp *.BMP);;" +
				I18n.get( "gui.uploadcover.browseimage.allfiles" ) + " (*)",
				self,
				nil,
				true
			)
			dialog.setCaption( I18n.get( "gui.uploadcover.browseimage.title" ) )
			dialog.setMode( Qt::FileDialog::ExistingFile )
			 if dialog.exec() == Qt::Dialog::Accepted
        		image_path = dialog.selectedFile()
				@image_path_lineedit.setText( image_path.strip() ) if ! QT3.empty_string?( image_path )
			end
		end

		def accept()
			aux = {
				"artist"	=> @artist_lineedit.text(),
				"album"		=> @album_lineedit.text(),
				"year"		=> @year_spinbox.value(),
				"month"		=> @month_spinbox.value(),
				"day"		=> @day_spinbox.value(),
				"tracks"	=> @tracks_text.text(),
				"reviewed"	=> @reviewed_checkbox.isChecked()
			}
			aux["image_path"] = @image_path_lineedit.text() if @values.include?( "image_path" )
			@values = aux
			super()
		end

	end


	class UploadCoverDialog < BaseDialog

		slots "browse_image()"

		def initialize( values )
			super( values )

			setCaption( I18n.get( "gui.uploadcover.title", values["site_name"] ) )

			album_group = Qt::GroupBox.new( 2, Qt::Horizontal, I18n.get( "gui.common.album" ), self )

			Qt::Label.new( I18n.get( "gui.common.artist" ), album_group )
			@artist_lineedit = Qt::LineEdit.new( values["artist"], album_group )

			Qt::Label.new( I18n.get( "gui.common.album" ), album_group )
			@album_lineedit = Qt::LineEdit.new( values["album"], album_group )

			Qt::Label.new( I18n.get( "gui.common.year" ), album_group )
			@year_spinbox = Qt::SpinBox.new( album_group )
			@year_spinbox.setMinValue( 1900 )
			@year_spinbox.setMaxValue( Date.today().year() )
			@year_spinbox.setValue( values["year"] )

			image_group = Qt::GroupBox.new( 3, Qt::Horizontal, I18n.get( "gui.common.image" ), self )

			Qt::Label.new( I18n.get( "gui.uploadcover.imagepath" ), image_group )
			@image_path_lineedit = Qt::LineEdit.new( values["image_path"], image_group )
			@image_path_lineedit.setText( values["image_path"] )

			@image_button = Qt::PushButton.new( "...", image_group )
			connect( @image_button, SIGNAL( "clicked()" ), self, SLOT( "browse_image()" ) )

			buttons = create_action_buttons()

			layout = Qt::VBoxLayout.new( self, 5 )
			layout.addWidget( album_group )
			layout.addWidget( image_group )
			layout.addLayout( buttons )

			resize( 400, 100 )
		end


		def browse_image()
			dirname = @image_path_lineedit.text().strip()
			dirname = QT3.empty_string?( dirname ) ? (ENV["HOME"] ? ENV["HOME"] : ".") : File.dirname( dirname )
			dialog = Qt::FileDialog.new(
				dirname,
				I18n.get( "gui.uploadcover.browseimage.images" ) + " (*.jpg *.JPG *.png *.PNG *.bmp *.BMP);;" +
				I18n.get( "gui.uploadcover.browseimage.allfiles" ) + " (*)",
				self,
				nil,
				true
			)
			dialog.setCaption( I18n.get( "gui.uploadcover.browseimage.title" ) )
			dialog.setMode( Qt::FileDialog::ExistingFile )
			if dialog.exec() == Qt::Dialog::Accepted
        		image_path = dialog.selectedFile()
				@image_path_lineedit.setText( image_path.strip() ) if ! QT3.empty_string?( image_path )
			end
		end

		def accept()
			@values = {
				"artist"		=> @artist_lineedit.text(),
				"album"			=> @album_lineedit.text(),
				"year"			=> @year_spinbox.value(),
				"image_path"	=> @image_path_lineedit.text()
			}
			super()
		end

	end

	class FixPagesDialog < BaseDialog

		slots "fetch_page()"
		slots "fix_page()"
		slots "submit_page()"

		def setText( text_edit, text )
			text_edit.clear()
			text_edit.append( text )
		end

		def initialize( values )
			super( values )

			@fetch_func = eval( @values["fetch_func"] )
			@fix_func = eval( @values["fix_func"] )
			@submit_func = eval( @values["submit_func"] )

			setCaption( "#{values["site_name"]} - #{values["title"]}" )

			url_label = Qt::Label.new( "<b>#{I18n.get( "gui.common.url" )}</b>", self )
			@url_lineedit = Qt::LineEdit.new( values["url"], self )

			@page_text = Qt::TextEdit.new( self )
			@page_text.setWordWrap( Qt::TextEdit::NoWrap )
			@page_text.setTextFormat( Qt::PlainText )
			@page_text.setFamily( "Monospace" )

			@fetch_button = Qt::PushButton.new( I18n.get( "gui.common.load" ), self )
			@fix_button = Qt::PushButton.new( I18n.get( "gui.common.fix" ), self )
			@submit_button = Qt::PushButton.new( I18n.get( "gui.common.submit" ), self )

			url_layout = Qt::HBoxLayout.new( 4 )
			url_layout.setDirection( Qt::BoxLayout::LeftToRight )
			url_layout.addWidget( url_label )
			url_layout.addWidget( @url_lineedit )

			buttons_layout = Qt::HBoxLayout.new( 4 )
			buttons_layout.addStretch()
			buttons_layout.addWidget( @fetch_button )
			buttons_layout.addWidget( @fix_button )
			buttons_layout.addWidget( @submit_button )

			layout = Qt::GridLayout.new( self, 9, 5, 5 )
			layout.addLayout( url_layout, 0, 0 )
			layout.addWidget( @page_text, 1, 0 )
			layout.addLayout( buttons_layout, 2, 0 )

			connect( @fetch_button, SIGNAL( "clicked()" ), self, SLOT( "fetch_page()" ) )
			connect( @fix_button, SIGNAL( "clicked()" ), self, SLOT( "fix_page()" ) )
			connect( @submit_button, SIGNAL( "clicked()" ), self, SLOT( "submit_page()" ) )

			resize( 600, 400 )
		end

		def fetch_page()
			if (page_content = @fetch_func.call( @url_lineedit.text() ))
				@original_content = page_content
				@original_url = @url_lineedit.text()
				setText( @page_text, page_content )
			end
		end

		def fix_page()
			setText( @page_text, @fix_func.call( @page_text.text() ) ) if @original_content
		end

		def submit_page()
			if @original_content != nil && @original_content != (page_content = @page_text.text())
				if @submit_func.call( @original_url, page_content )
					@original_content = page_content
					puts I18n.get( "gui.fixpages.success", @original_url )
				else
					puts I18n.get( "gui.fixpages.error", @original_url )
				end
			end
		end

	end


	class SearchLyricsDialog < BaseDialog

		def initialize( values )
			super( values )

			setCaption( I18n.get( "gui.searchlyrics.title" ) )

			group = Qt::GroupBox.new( 2, Qt::Horizontal, I18n.get( "gui.searchlyrics.search" ), self )

			Qt::Label.new( I18n.get( "gui.common.artist" ), group )
			@artist_lineedit = Qt::LineEdit.new( values["artist"], group )

			Qt::Label.new( I18n.get( "gui.common.song" ), group )
			@title_lineedit = Qt::LineEdit.new( values["title"], group )

			Qt::Label.new( I18n.get( "gui.common.album" ), group )
			@album_lineedit = Qt::LineEdit.new( values["album"], group )

			Qt::Label.new( I18n.get( "gui.common.year" ), group )
			@year_spinbox = Qt::SpinBox.new( group )
			@year_spinbox.setMinValue( 1900 )
			@year_spinbox.setMaxValue( Date.today().year() )
			@year_spinbox.setValue( values["year"] )

			buttons = create_action_buttons()

			layout = Qt::VBoxLayout.new( self, 5 )
			layout.addWidget( group )
			layout.addLayout( buttons )

			resize( 300, 100 )
		end

		def accept()
			@values = {
				"artist" => @artist_lineedit.text(),
				"title"  => @title_lineedit.text(),
				"album"  => @album_lineedit.text(),
				"year"   => @year_spinbox.value(),
			}
			super()
		end

	end


	class ShowLyricsDialog < BaseDialog

		def initialize( values )
			super( values )

			title = I18n.get( "gui.lyrics.title", @values["title"], @values["artist"] )
			title += " [#{@values["site_name"]}]" if @values["site_name"]
			setCaption( title )

			@lyrics_text = Qt::TextEdit.new( self )
			@lyrics_text.setTextFormat( Qt::RichText )
			@lyrics_text.setText( "<qt>" + values["lyrics"].gsub( "\n", "<br/>" ) + "</qt>" )

			layout = Qt::GridLayout.new( self, 1, 1, 5 )
			layout.addWidget( @lyrics_text, 0, 0 )

			resize( 350, 400 )
		end

	end


end
